package com.foolishbird.sdk.ui.activity;

import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.FragmentActivity;

import com.foolishbird.sdk.assist.CallbackObservable;
import com.foolishbird.sdk.assist.Constant;
import com.foolishbird.sdk.handler.SimpleAsyncResponseHandler;
import com.foolishbird.sdk.params.BindPhoneResponseParams;
import com.foolishbird.sdk.params.ResponseParams;
import com.foolishbird.sdk.params.bean.State;
import com.foolishbird.sdk.ui.view.DialogFactory;
import com.foolishbird.sdk.ui.view.ProgressDialog;
import com.foolishbird.sdk.utils.ResUtils;
import com.foolishbird.sdk.utils.ToolsUtils;
import com.foolishbird.sdk.utils.WL;


public abstract class AppBaseActivity extends FragmentActivity {

    private static final String TAG = AppBaseActivity.class.getSimpleName();

    private static final int REQUEST_FINE_LOCATION = 0;

    private boolean isSendHttpRequesting = false;

    private boolean isStoped = true;

    private boolean isSaveInstanceState = false;

    public final int getViewIdentifier(String name) {
        return ResUtils.getViewIdentifier(this, name);
    }

    public final int getLayoutIdentifier(String name) {
        return ResUtils.getLayoutIdentifier(this, name);
    }

    public final int getStringIdentifier(String name) {
        return ResUtils.getStringIdentifier(this, name);
    }

    public final int getAnimationIdentifier(String name) {
        return ResUtils.getAnimationIdentifier(this, name);
    }

    protected final boolean checkAppSelfPermission(String permission) {
        WL.d(TAG, "checkAppSelfPermission---> " + permission);
        if (!ToolsUtils.checkAppSelfPermission(this, permission)) {
            ActivityCompat.requestPermissions(this, new String[]{permission}, REQUEST_FINE_LOCATION);
            return false;
        }
        return true;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        int grantResult = grantResults.length > 0 ? grantResults[0] : PackageManager.PERMISSION_DENIED;
        String permission = (permissions != null && permissions.length > 0) ? permissions[0] : "";
        switch (grantResult) {
            case PackageManager.PERMISSION_GRANTED:
                WL.d(TAG, "onRequestPermissionsResult " + permission + " is PERMISSION_GRANTED");
                onRequestPermissionsGranted(permission);
                break;
            case PackageManager.PERMISSION_DENIED:
                WL.d(TAG, "onRequestPermissionsResult " + permission + " is PERMISSION_DENIED");
                onRequestPermissionsDenied(permission);
                break;
            default:
                WL.d(TAG, "onRequestPermissionsResult " + permission + " result is " + grantResult);
        }
    }

    protected void onRequestPermissionsGranted(String permission) {

    }

    protected void onRequestPermissionsDenied(String permission) {

    }

    protected boolean isForbidBackSuper() {
        return isSendHttpRequesting;
    }

    protected View getSubmitButton() {
        return null;
    }

    /**
     * Hidden virtual keys and full screen
     */
    protected void hideVirtualKeysAndFullScreen() {
        if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) {
            View v = this.getWindow().getDecorView();
            v.setSystemUiVisibility(View.GONE);
        } else if (Build.VERSION.SDK_INT >= 19) {
            View decorView = getWindow().getDecorView();
            int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_FULLSCREEN;
            decorView.setSystemUiVisibility(uiOptions);
        }
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Configuration config = getResources().getConfiguration();
        if (Configuration.ORIENTATION_PORTRAIT != config.orientation) {
            hideVirtualKeysAndFullScreen();
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_BEHIND);
        }
    }

    @Override
    public void onBackPressed() {
        if (!isForbidBackSuper()) {
            super.onBackPressed();
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        this.isStoped = false;
    }

    @Override
    protected void onResume() {
        super.onResume();
        this.isStoped = false;
        this.isSaveInstanceState = false;
    }

    @Override
    protected void onStop() {
        super.onStop();
        this.isStoped = true;
    }

    protected boolean isStoped() {
        return this.isStoped;
    }

    @Override
    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        this.isSaveInstanceState = false;
    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        this.isSaveInstanceState = true;
        super.onSaveInstanceState(outState);
    }

    protected boolean isSaveInstanceState() {
        return isSaveInstanceState;
    }

    private void setSubmitButtonEnabled(boolean enabled) {
        View view = getSubmitButton();
        if (view != null) {
            view.setEnabled(enabled);
        }
    }

    public final SimpleAsyncResponseHandler requestCallbackHandler(Class<? extends ResponseParams> paramsClass, Object... params) {
        return new AsyncCallbackHandler(paramsClass, params);
    }

    public void onAsyncRequestCancel(int flag, Object... params) {
        isSendHttpRequesting = false;
        setSubmitButtonEnabled(true);
        WL.d(TAG, "onAsyncReuqestCancel ---> flag: " + flag);
    }

    public void onAsyncRequestStart(int flag, Object... params) {
        isSendHttpRequesting = true;
        setSubmitButtonEnabled(false);
        WL.d(TAG, "onAsyncReuqestStart ---> flag: " + flag);
    }

    public void onAsyncRequestNetworkException(int flag, Exception ex) {
        isSendHttpRequesting = false;
        setSubmitButtonEnabled(true);
        WL.d(TAG, "onAsyncReuqestNetworkException ---> flag: " + flag);
        CallbackObservable.getInstance().callExcetion(Constant.CallType.CALL_LOGIN, ex);
    }

    public void onAsyncRequestException(int flag, Exception ex) {
        isSendHttpRequesting = false;
        setSubmitButtonEnabled(true);
        WL.d(TAG, "onAsyncReuqestException ---> flag: " + flag);
        CallbackObservable.getInstance().callExcetion(Constant.CallType.CALL_LOGIN, ex);
    }

    public void onAsyncRequestResult(int flag, ResponseParams response, Object... params) {
        isSendHttpRequesting = false;
        setSubmitButtonEnabled(true);
        WL.d(TAG, "onAsyncReuqestResult ---> flag: " + flag);
    }

    private class AsyncCallbackHandler<T extends ResponseParams> extends SimpleAsyncResponseHandler<T> implements Handler.Callback {

        private static final int MSG_SHOW_PROGRESSBAR = 0;
        private static final int MSG_DISMISS_PROGRESSBAR = 1;

        private final Handler mHandler;
        private final Object[] params;
        private final boolean autoLogin;
        private ProgressDialog dialog;

        public AsyncCallbackHandler(Class<T> responseParams, Object... params) {
            super(responseParams);
            this.params = params;
            this.autoLogin = params != null && params.length >= 3 && Boolean.parseBoolean((String) params[2]);
            dialog = DialogFactory.createProgressDialog(AppBaseActivity.this);
            mHandler = new Handler(getMainLooper(), this);
        }

        void sendShowProgressbarMessage() {
            mHandler.removeMessages(MSG_SHOW_PROGRESSBAR);
            mHandler.removeMessages(MSG_DISMISS_PROGRESSBAR);
            mHandler.sendEmptyMessageDelayed(MSG_SHOW_PROGRESSBAR, 500);
        }

        void sendDismissProgressbarMessage() {
            mHandler.removeMessages(MSG_SHOW_PROGRESSBAR);
            mHandler.removeMessages(MSG_DISMISS_PROGRESSBAR);
            mHandler.sendEmptyMessage(MSG_DISMISS_PROGRESSBAR);
        }

        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_SHOW_PROGRESSBAR:
                    if (dialog != null && !isStoped()) {
                        dialog.show();
                    }
                    break;
                case MSG_DISMISS_PROGRESSBAR:
                    if (dialog != null && !isStoped()) {
                        dialog.dismiss();
                        dialog = null;
                    }
                    break;

                default:
            }
            return true;
        }

        public void onAsyncCancel(int flag) {
            sendDismissProgressbarMessage();
            onAsyncRequestCancel(flag, params);
        }

        public void onAsyncSendRequest(int flag) {
            sendShowProgressbarMessage();
            onAsyncRequestStart(flag, params);
        }

        public void onAsyncException(int flag, Exception ex) {
            sendDismissProgressbarMessage();
            onAsyncRequestException(flag, ex);
        }

        public void onAsyncNetworkException(int flag, Exception ex) {
            sendDismissProgressbarMessage();
            DialogFactory.createConfirmDialog(AppBaseActivity.this, getString(getStringIdentifier("hnssn_hint_network"))).show();
            onAsyncRequestNetworkException(flag, ex);
        }

        @Override
        public void onAsyncResponseSuccess(int flag, T response) {
            sendDismissProgressbarMessage();

            if (response != null && !isStoped() && !autoLogin) {
                if (State.SUCCESS != response.getState().getCode()) {
                    if(110 == response.getState().getCode()){
                        BindPhoneResponseParams message = (BindPhoneResponseParams)response;
                        DialogFactory.createIDFaildDialog(AppBaseActivity.this, message).show();
                    }else {
                        String message = response.getState().getMsg();
                        DialogFactory.createConfirmDialog(AppBaseActivity.this, message).show();
                    }


                }
            }

            onAsyncRequestResult(flag, response, params);
        }

    }

}
